using System;
using System.Collections.Generic;
using IQIGame.Onigao.GameAOT;

namespace IQIGame.Onigao.GamePlay
{
    public class BattleRenderHideController : TController
    {
        private Dictionary<UnitView, int> _hideDict = new Dictionary<UnitView, int>();
        private Dictionary<UnitView, int> _hideWidgetDict = new Dictionary<UnitView, int>();
        private int _sceneHide;
        private int _uiHide;

        // 临时字典
        private Dictionary<UnitView, int> _tempDict = new Dictionary<UnitView, int>();
        // 脏标记
        private bool dirty;

        protected override void OnUpdate(float deltaTime)
        {
            base.OnUpdate(deltaTime);
            if (this.dirty)
            {
                this._tempDict.AddRange(this._hideDict);
                foreach (var rPair in this._tempDict)
                {
                    var rViewComp = rPair.Key.GetComponent<UnitViewComponent>(ETComponentType.UnitViewComponent);
                    if (rPair.Value > 0)
                    {
                        rViewComp.active = false;
                    }
                    else
                    {
                        this._hideDict.Remove(rPair.Key);
                        var rDeadComp = rViewComp.unit.GetComponent<DeadViewComponent>(ETComponentType.DeadViewComponent);
                        if (rDeadComp == null || !rDeadComp.realDead)
                        {
                            rViewComp.active = true;
                        }
                    }
                }
                this._tempDict.Clear();
                this._tempDict.AddRange(this._hideWidgetDict);
                foreach (var rPair in this._tempDict)
                {
                    var rViewComp = rPair.Key.GetComponent<UnitViewComponent>(ETComponentType.UnitViewComponent);
                    if (rPair.Value > 0)
                    {
                        rViewComp.widgetActive = false;
                    }
                    else
                    {
                        this._hideWidgetDict.Remove(rPair.Key);
                        rViewComp.widgetActive = true;
                    }
                }
                this._tempDict.Clear();
                
                BattleManager.Instance.ctrl.sceneCtrl.scene.SetActive(this._sceneHide <= 0);
                BattleManager.Instance.ctrl.orderCtrl.ShowUI(this._uiHide <= 0);

                this.dirty = false;
            }
        }

        public void AddUnit(List<UnitView> units, bool onlyWidget)
        {
            var rDict = onlyWidget ? this._hideWidgetDict : this._hideDict;
            for (int i = 0; i < units.Count; i++)
            {
                var rUnit = units[i];
                rDict.TryGetValue(rUnit, out var nCount);
                rDict[rUnit] = nCount + 1;
            }
            this.dirty = true;
        }

        public void RemoveUnit(List<UnitView> units, bool onlyWidget)
        {
            var rDict = onlyWidget ? this._hideWidgetDict : this._hideDict;
            for (int i = 0; i < units.Count; i++)
            {
                var rUnit = units[i];
                if (rDict.TryGetValue(rUnit, out var nCount))
                {
                    rDict[rUnit] = nCount - 1;
                }
            }
            this.dirty = true;
        }

        public void Add(int nHideType)
        {
            switch (nHideType)
            {
                case 0:
                    this._sceneHide++;
                    break;
                case 1:
                    this._uiHide++;
                    break;
            }
            this.dirty = true;
        }

        public void Remove(int nHideType)
        {
            switch (nHideType)
            {
                case 0:
                    this._sceneHide = Math.Max(0, this._sceneHide - 1);
                    break;
                case 1:
                    this._uiHide = Math.Max(0, this._uiHide - 1);
                    break;
            }
            this.dirty = true;
        }

        protected override void OnDispose()
        {
            this._hideDict.Clear();
        }
    }
}